﻿using System;
using System.Linq;
using System.Drawing;

using Spencen.Mobile.UI.Transforms;

namespace Spencen.Mobile.UI.Primitives
{
    public class TextElement : RectangleElement
    {
        private bool _requiresAutoSizing = true;

        public readonly static Font DefaultFont = new Font( FontFamily.GenericSansSerif, 11, FontStyle.Regular );
        public readonly static Brush DefaultForeground = new SolidBrush( Color.Black );

        public TextElement() : base()
        {
            Foreground = DefaultForeground;
            Background = null;
            Stroke = null;
            Font = DefaultFont;
        }

        public string Text { get; set; }
        public Brush Foreground { get; set; }
        public Font Font { get; set; }
        public bool AutoSize { get; set; }

        protected override void OnRender( GraphicsContext context )
        {
            base.OnRender( context );

            var points = GeneratePoints();
            var transformedPoints = context.TransformedPoints( points );

            // Very rough font scaling
            if ( AutoSize && ( _requiresAutoSizing || context.IsScaled ) )
            {
                _requiresAutoSizing = false;
                var size = context.Graphics.MeasureString( Text, DefaultFont );
                var xRatio = DrawingSupport.DistanceBetweenPoints( transformedPoints[0], transformedPoints[1] ) / size.Width;
                var yRatio = DrawingSupport.DistanceBetweenPoints( transformedPoints[0], transformedPoints[3] ) / size.Height;
                var fontScaling = Math.Max( 4.0f, Math.Min( xRatio, yRatio ) * DefaultFont.Size );
                if ( Font.Size != fontScaling )
                {
                    var oldFont = Font;
                    Font = new Font( Font.Name, fontScaling, Font.Style );
                    if ( oldFont != DefaultFont ) oldFont.Dispose();
                }
            }

            var rotationTransform = Transforms.OfType<RotateTransform>().FirstOrDefault( t => t.Angle != 0.0f );

            using ( Font textFont = DrawingSupport.CreateRotatedFont( context.Graphics, Font.Name, Font.Size, (int)( rotationTransform == null ? 360 - Angle : 360 - rotationTransform.Angle ) ) )
            {
                var textSize = context.Graphics.MeasureString( Text, textFont );
                var width = transformedPoints[ 2 ].X - transformedPoints[ 0 ].X;
                var height = transformedPoints[ 2 ].Y - transformedPoints[ 0 ].Y;
                var transformedBounds = TransformedBounds( context );

                var centerPoint = new Point( ( points[ 2 ].X - points[ 0 ].X ) / 2, ( points[ 2 ].Y - points[ 0 ].Y ) / 2 );
                centerPoint.X -= (int) textSize.Width / 2;
                centerPoint.Y -= (int) textSize.Height / 2;
                var transformedTextPoints = context.TransformedPoints( new Point[] { centerPoint } );

                context.Graphics.DrawString( Text, textFont, Foreground,
                    new RectangleF( transformedTextPoints[ 0 ].X, transformedTextPoints[ 0 ].Y, transformedBounds.Width, transformedBounds.Height ),
                    new StringFormat() { FormatFlags = StringFormatFlags.NoClip } );
            } 
        }

        protected override void OnResize()
        {
            base.OnResize();
            _requiresAutoSizing = true;
        }
    }
}
